package org.redswallow.filter;

import java.util.Locale;
import java.util.ResourceBundle;

import javax.servlet.FilterConfig;

import org.redswallow.filter.dispatch.PluginInvoker;
import org.redswallow.log.LogFactory;
import org.redswallow.util.config.ConfigConstants;
import org.redswallow.util.config.DelegatingPropertySet;
import org.redswallow.util.config.FilterPropertySet;
import org.redswallow.util.config.IPropertySet;
import org.redswallow.util.config.ResourceBundlePropertySet;
import org.slf4j.Logger;

final class RedSwallowContext {
	
	
	private IPropertySet _propertySet ;
	
	private static RedSwallowContext _context;
	
	private PluginInvoker _pluginInvoker;
	
	private Logger log = LogFactory.getLog(RedSwallowContext.class);
	
	private RedSwallowContext(FilterConfig filterConfig) {
		
		assert filterConfig != null;
		
		_propertySet = createPropertySet(filterConfig);
		
	}
	
	public void setPluginInvoker(PluginInvoker invoker) {
		_pluginInvoker = invoker;
	}
	
	public PluginInvoker getPluginInvoker() {
		return _pluginInvoker;
	}
	
	public static RedSwallowContext getInstance(FilterConfig filterConfig) {
		if (_context == null) {
			_context =  new RedSwallowContext(filterConfig);
		}
		return _context;
	}
	
	private IPropertySet createPropertySet(FilterConfig filterConfig) {
		
		log.debug("createPropertySet begin.");
		
		DelegatingPropertySet result = new DelegatingPropertySet();
		
		Locale currentLocale = Locale.getDefault();
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
		if (cl == null) {
		    cl = ClassLoader.getSystemClassLoader();
		}
		
		result.addSource(new ResourceBundlePropertySet
					(ResourceBundle.getBundle(ConfigConstants.DEFAULT_XSS_CHECKER_PROPERTY, currentLocale, cl)));
		
		log.debug("addSource property {} ok.", ConfigConstants.DEFAULT_XSS_CHECKER_PROPERTY);
		
		result.addSource(new FilterPropertySet(filterConfig));
		
		log.debug("addSource FilterPropertySet ok.");
		
		log.debug("createPropertySet end.");
		
		return result;
	}
	
	public IPropertySet getPropertySet() {
		return _propertySet;
	}
		
}
